#include "stdafx.h"
#include "AntiWarden.h"
#include "hwbrk.h"

initialiseSingleton(CAntiWarden);

CAntiWarden::CAntiWarden(DWORD hh)
{
    m_oHook.initData(hh);
    m_oHook.hookData(NtQuery);
    m_Ary[eVirQey].Init(m_oHook.GetHookFun());

}

CAntiWarden::~CAntiWarden()
{
    //Remove();
}

LONG NTAPI CAntiWarden::MyVecExepHander(PEXCEPTION_POINTERS ExceptionInfo)
{
    LONG bRet = EXCEPTION_CONTINUE_SEARCH;
    PEXCEPTION_RECORD pER = ExceptionInfo->ExceptionRecord;
    PCONTEXT pCT = ExceptionInfo->ContextRecord;
    pCT->Dr0 = 0;
    pCT->Dr1 = 0;
    pCT->Dr2 = 0;
    pCT->Dr3 = 0;
    pCT->Dr6 = 0;
    pCT->Dr7 = 0;
    if (getSingleton().m_Ary[eVirQey].GetHook() == pER->ExceptionAddress)
    {
        bRet = EXCEPTION_CONTINUE_EXECUTION;
        pCT->Eip = (DWORD)(CAntiWarden::NtQuery);
    }
    else if (getSingleton().m_Ary[eGetCon].GetHook() == pER->ExceptionAddress)
    {
        bRet = EXCEPTION_CONTINUE_EXECUTION;
        pCT->Eip = (DWORD)(CAntiWarden::NtThreadCon);
    }
    else if (AddVectoredExceptionHandler == pER->ExceptionAddress)
    {
        MessageBoxA(0,0,0,0);
        bRet = EXCEPTION_CONTINUE_EXECUTION;
        *(DWORD*)(pCT->Esp+4 ) = 0;
        pCT->Eip = pCT->Eip + 2;
        //RemoveHardwareBreakpoint(getSingleton().m_Hooks[eAddVec]);
    }
    return bRet;
}

void CAntiWarden::HookAddVec(HANDLE hThread)
{
    //if (!m_Hooks[eSellHandler])
    //{
    //    //RemoveVectoredExceptionHandler(m_Hooks[eSellHandler]);
    //    //m_Hooks[eSellHandler] = NULL;
    //    //AddVectoredContinueHandler()
    //    m_Hooks[eSellHandler] = AddVectoredExceptionHandler(TRUE, CAntiWarden::MyVecExepHander);
    //}
}

void CAntiWarden::RemoveAdd()
{
    //if (m_Hooks[eSellHandler])
    //{
    //    RemoveVectoredExceptionHandler(m_Hooks[eSellHandler]);
    //    m_Hooks[eSellHandler] = NULL;
    //    //AddVectoredContinueHandler()
    //}
}

void CAntiWarden::FunHook(HANDLE hThread)
{
    //if (!m_Hooks[eVirQey])
    //{
    //    HMODULE hNT = GetModuleHandle(_T("ntdll.dll"));
    //    m_Ary[eVirQey].Init(GetProcAddress(hNT, "ZwQueryVirtualMemory"));
    //    m_Hooks[eVirQey] = SetHardwareBreakpoint(hThread, HWBRK_TYPE_CODE, HWBRK_SIZE_1, m_Ary[eVirQey].GetHook());
    //}
    //if (!m_Hooks[eAddVec])
    //{

    //    HMODULE hKer = GetModuleHandle(_T("kernel32.dll"));
    //    HANDLE hFun = GetProcAddress(hKer, "AddVectoredExceptionHandler");
    //    m_Hooks[eAddVec] = SetHardwareBreakpoint(hThread, HWBRK_TYPE_CODE, HWBRK_SIZE_1, hFun);
    //}
}

void CAntiWarden::Remove()
{
    //for (int i = 0; i < eSellHandler; i++)
    //{
    //    if (m_Hooks[i])
    //    {
    //        RemoveHardwareBreakpoint(m_Hooks[i]);
    //        m_Hooks[i] = 0;
    //    }
    //}
    //if (m_Hooks[eSellHandler])
    //{
    //    RemoveVectoredExceptionHandler(m_Hooks[eSellHandler]);
    //    m_Hooks[eSellHandler] = 0;
    //}
    
}

SIZE_T CAntiWarden::NtQuery( __in HANDLE hProcess, __in_opt LPCVOID lpAddress, __in DWORD dwZero, __out PMEMORY_BASIC_INFORMATION lpBuffer, __in SIZE_T dwLength, __out DWORD& pSize )
{
    CMyNTCall::_hookFun _MyFun = (CMyNTCall::_hookFun)getSingleton().m_Ary[eVirQey].GetHookFun();
    SIZE_T Ret = _MyFun(hProcess, lpAddress, 0, lpBuffer, dwLength, &pSize);
    PMEMORY_BASIC_INFORMATION pBuf = (PMEMORY_BASIC_INFORMATION)lpBuffer;
    DWORD dw = (SIZE_T)pBuf->BaseAddress;
    if (dw + pBuf->RegionSize == getSingleton().m_hDll)
    {
        pBuf->RegionSize += getSingleton().m_hSize;
    }
    return Ret;
}

BOOL CAntiWarden::NtThreadCon( __in HANDLE hThread, __inout LPCONTEXT lpContext )
{
    CMyNTCall::_hookFun _MyFun = (CMyNTCall::_hookFun)getSingleton().m_Ary[eGetCon].GetHookFun();
    return _MyFun(hThread, lpContext);
}

BOOL CAntiWarden::NtReadPro(__in HANDLE hProcess, __in LPCVOID lpBaseAddress, __out LPVOID lpBuffer, __in SIZE_T nSize, __out_opt SIZE_T * lpNumberOfBytesRead)
{
    CMyNTCall::_hookFun _MyFun = (CMyNTCall::_hookFun)getSingleton().m_Ary[eGetCon].GetHookFun();
    return _MyFun(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead);
}